package com.edu.learning.concurrent.sample.mode4;

import java.util.Random;
import java.util.concurrent.*;

import static java.util.concurrent.TimeUnit.SECONDS;

/**
 * @author ll
 * @Date 2017/10/26 15:40
 */
public class TransferQueueDemo2 {
    public static void main(String[] args) {
        TransferQueue<String> queue = new LinkedTransferQueue<>();
        ExecutorService executorService = new ThreadPoolExecutor(
                16,
                16,
                10,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(1024),
                new ThreadPoolExecutor.CallerRunsPolicy());
        executorService.submit(new Producer("Producer1 ", queue));
        executorService.submit(new Producer("Producer2 ", queue));
        executorService.submit(new Consumer("Consumer1 ", queue));
        executorService.submit(new Consumer("Consumer2 ", queue));
        executorService.shutdown();
    }

    static class Producer implements Runnable {
        private final String name;
        private final TransferQueue<String> queue;

        public Producer(String name, TransferQueue<String> queue) {
            this.name = name;
            this.queue = queue;
        }

        @Override
        public void run() {
            System.out.println(name + " begin transfer objects");
            try {
                for (int i = 0; i < 5; i ++) {
                    queue.transfer(" _Product " + i);
                    System.out.println(name + " transfer " + name + "_Product " + i);
                }
                System.out.println(name + " after transformation");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(name + " is over");
        }
    }

    static class Consumer implements Runnable {
        private final String name;
        private final TransferQueue<String> queue;
        private static Random random = new Random(System.currentTimeMillis());

        public Consumer(String name, TransferQueue<String> queue) {
            this.name = name;
            this.queue = queue;
        }

        @Override
        public void run() {
            try {
                for (int i = 0; i < 5; i ++) {
                    String str = queue.take();
                    System.out.println(name + " _take " + str);
                    SECONDS.sleep(random.nextInt(5));
                }
                System.out.println(name + " is over");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
